package sm.pzavoli.std;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import android.util.Log;

public class Lista implements List<StdPojo> {
	ArrayList<StdPojo> m_lista = new ArrayList<StdPojo>();
	HashMap<String,StdPojo> m_keymap = new HashMap<String,StdPojo>();
	Class<? extends StdPojo> m_classePojo;	

	public Lista(Class<? extends StdPojo> classePojo) {
		m_classePojo = classePojo;
	}

	/*
	 * Crea un nuovo pojo del tipo identificato da questa relazione
	 */
	public StdPojo createNewPojo() {
		try {
			StdPojo m_pojo = null;
			try {
				m_pojo = m_classePojo.newInstance();
			} catch(IllegalAccessException ex) {
				m_pojo = null;
			} catch(InstantiationException ex) {
				m_pojo = null;
			}	
			return m_pojo;
		} catch(Exception e) {
			e.printStackTrace();
			Log.e("Lista","createNewPojo, errore:"+e.getMessage());
			return null;
		}
	}
	
	@Override
	public boolean add(StdPojo pojo) {
		String key = pojo.getKeyString();
		if ( key != null) {
			if ( !m_keymap.containsKey(key)) {
				m_lista.add(pojo);
				m_keymap.put(key, pojo);
			}
			else
				return false;
		}
		return true;
	}

	@Override
	public void add(int index, StdPojo pojo) {
		m_lista.add(index, pojo);
		m_keymap.put(pojo.getKeyString(), pojo);
	}

	@Override
	public boolean addAll(Collection<? extends StdPojo> collection) {
		return m_lista.addAll(collection);
	}

	@Override
	public boolean addAll(int index, Collection<? extends StdPojo> collection) {
		return m_lista.addAll(index, collection);
	}

	@Override
	public void clear() {
		m_lista.clear();
		m_keymap.clear();
	}

	@Override
	public boolean contains(Object arg0) {
		if ( arg0 instanceof StdPojo) {
			String key = ((StdPojo)arg0).getKeyString();
			return m_keymap.containsKey(key);
		}
		if ( arg0 instanceof String) {
			String key = ((String)arg0);
			return m_keymap.containsKey(key);
		}		
		return false;
	}

	@Override
	public boolean containsAll(Collection<?> collection) {
		return m_lista.containsAll(collection);
	}

	@Override
	public StdPojo get(int indice) {
		return m_lista.get(indice);
	}

	/*
	 * Ricerca nella lista il pdc che ha come chiave key
	 */
	public StdPojo get(String key) {
		if ( m_keymap.containsKey(key)) {
			return m_keymap.get(key);
		}
		return null;
	}

	@Override
	public int indexOf(Object pojo) {
		return m_lista.indexOf(pojo);
	}

	@Override
	public boolean isEmpty() {
		return m_lista.isEmpty();
	}

	@Override
	public Iterator<StdPojo> iterator() {
		return m_lista.iterator();
	}

	@Override
	public int lastIndexOf(Object pojo) {
		return m_lista.lastIndexOf((StdPojo)pojo);
	}

	@Override
	public ListIterator<StdPojo> listIterator() {
		return m_lista.listIterator();
	}

	@Override
	public ListIterator<StdPojo> listIterator(int location) {
		return m_lista.listIterator(location);
	}

	@Override
	public StdPojo remove(int index) {
		StdPojo pojo = m_lista.get(index);
		if ( pojo != null) {
			m_keymap.remove(pojo.getKeyString());
			m_lista.remove(index);
		}
		return pojo;
	}

	@Override
	public boolean remove(Object pojo) {
		try {
			m_lista.remove(pojo);
			m_keymap.remove(((StdPojo)pojo).getKeyString());
		} catch(Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	@Override
	public boolean removeAll(Collection<?> arg0) {
		m_lista.removeAll(arg0);
		return true;
	}

	@Override
	public boolean retainAll(Collection<?> arg0) {
		m_lista.retainAll(arg0);
		return true;
	}

	@Override
	public StdPojo set(int index, StdPojo pojo) {
		return m_lista.set(index, pojo);
	}

	@Override
	public int size() {
		return m_lista.size();
	}

	@Override
	public List<StdPojo> subList(int start, int end) {
		return m_lista.subList(start, end);
	}

	@Override
	public Object[] toArray() {
		return m_lista.toArray();
	}

	@Override
	public <T> T[] toArray(T[] contents) {
		return m_lista.toArray(contents);
	}

}
